﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

class VDPlayer
{
    private IntPtr playerPtr;
    private GCHandle handle;
    private Action<_DemuxInfo> openCb;

    public event Action<_Frame> OnFrameCb;

    public bool Closed {
        get;
        private set;
    }

    public long Duration
    {
        get;
        private set;
    }

    public double Progress
    {
        get { return GetProgress(); }
    }

    public bool IsPlaying
    {
        get { return GetIsPlaying(); }
    }
    public VDPlayer()
    {
        handle = GCHandle.Alloc(this);
        playerPtr = VDModule.CreateVDPlayer(GCHandle.ToIntPtr(handle));
        Duration = 0;
    }

    public void Close()
    {
        if (playerPtr == IntPtr.Zero) return;
        Closed = true;
        VDModule.Close(playerPtr);
    }

    public void Open(string url, Action<_DemuxInfo> callback)
    {
        if (playerPtr == IntPtr.Zero) return;
        Closed = false;
        openCb = callback;
        VDModule.Open(playerPtr, Encoding.UTF8.GetBytes(url), VDModule.demuxCallBack);
    }

    public void OpenCallback(_DemuxInfo info)
    {
        if(info.retcode == 0)
        {
            Duration = info.duration;
        }
        if (openCb != null)
            openCb(info);
    }

    public bool StartDemux(bool playVideo, bool tryPlayAudio)
    {
        if (playerPtr == IntPtr.Zero) return false;
        return VDModule.StartDemux(playerPtr, playVideo, tryPlayAudio, VDModule.frameCallBack) == 0 ? true : false;
    }

    /// <summary>
    /// VDModule的回掉函数，输出一帧数据
    /// </summary>
    /// <param name="frame"></param>
    public void OnFrame(_Frame frame)
    {
        if(OnFrameCb != null)
            OnFrameCb(frame);
    }

    public void SetOption(VDOptionType type, int value)
    {
        if (playerPtr == IntPtr.Zero) return;
        VDModule.SetOption(playerPtr, (int)type, value);
    }

    public void Play()
    {
        if (playerPtr == IntPtr.Zero) return;
        VDModule.Play(playerPtr);
    }
    public void Pause()
    {
        if (playerPtr == IntPtr.Zero) return;
        VDModule.Pause(playerPtr);
    }
    public void Seek(double seekpos)
    {
        if (playerPtr == IntPtr.Zero) return;
        VDModule.Seek(playerPtr, seekpos);
    }
    public void SetAudioTrack(int index)
    {
        if (playerPtr == IntPtr.Zero) return;
        VDModule.SetAudioTrack(playerPtr, index);
    }
    private double GetProgress()
    {
        if (playerPtr == IntPtr.Zero) return 0;
        return VDModule.GetProgress(playerPtr);
    }

    private bool GetIsPlaying()
    {
        if (playerPtr == IntPtr.Zero) return false;
        return VDModule.GetIsPlaying(playerPtr) == 0 ? true : false;
    }

    public bool ScreenShot(ref int width, ref int height, ref IntPtr data)
    {
        if (playerPtr == IntPtr.Zero) return false;
        if (data != IntPtr.Zero) return false;
        return VDModule.ScreenShot(playerPtr, ref width, ref height, ref data) == 0 ? true : false;
    }

    public void SetCameraRect(int width, int height)
    {
        if (playerPtr == IntPtr.Zero) return;
        VDModule.SetCameraRect(playerPtr, width,height);
    }

    public void Release()
    {
        if (playerPtr == IntPtr.Zero) return;
        //VDModule.Close(playerPtr, null);
        VDModule.DeleteVDPlayer(playerPtr);
        playerPtr = IntPtr.Zero;
        handle.Free();
    }
    ~VDPlayer()
    {
        Release();
    }
}